Skip to content

Conversation

@folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Oct 15, 2025

tracking issue: #140364
closes #140364

Reference PR:

Request for Stabilization

Summary

The cfg_asm feature allows #[cfg(...)] and #[cfg_attr(...)] on the arguments of the assembly macros, for instance:

asm!( // or global_asm! or naked_asm!
    "nop",
    #[cfg(target_feature = "sse2")]
    "nop",
    // ...
    #[cfg(target_feature = "sse2")]
    a = const 123, // only used on sse2
);

Semantics

Templates, operands, options and clobber_abi in the assembly macros (asm!, naked_asm! and global_asm!) can be annotated with #[cfg(...)] and #[cfg_attr(...)]. When the condition evaluates to true, the annotated argument has no effect, and is completely ignored when expanding the assembly macro.

Documentation

reference PR: rust-lang/reference#2063

Tests

History

Resolved questions

how are other attributes handled

Other attributes are parsed, but explicitly rejected.

unresolved questions

operand before template

The current implementation expects at least one template string before any operands. In the example below, if the cfg condition evaluates to true, the assembly block is ill-formed. But even when it evaluates to false this block is rejected, because the parser still expects just a template (a template is parsed as an expression and then validated to ensure that it is or expands to a string literal).

Changing how this works is difficult.

// This is rejected because `a = out(reg) x` does not parse as an expresion.
asm!(
	#[cfg(false)]
	a = out(reg) x, //~ ERROR expected token: `,`
	"",
);

lint on positional arguments?

Adding a lint to warn on the definition or use of positional arguments being cfg'd out was discussed in #140279 (comment) and subsequent comments. Such a lint is not currently implemented, but that may not be a blocker based on the comments there.

r? @traviscross (I'm assuming you'll reassign as needed)

@rustbot rustbot added A-compiler-builtins Area: compiler-builtins (https://github.com/rust-lang/compiler-builtins) S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 15, 2025
@folkertdev folkertdev added the I-lang-nominated Nominated for discussion during a lang team meeting. label Oct 16, 2025
@folkertdev folkertdev marked this pull request as ready for review October 16, 2025 08:31
@rustbot
Copy link
Collaborator

rustbot commented Oct 16, 2025

compiler-builtins is developed in its own repository. If possible, consider making this change to rust-lang/compiler-builtins instead.

cc @tgross35

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 16, 2025
@traviscross traviscross added I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang T-lang Relevant to the language team and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 16, 2025
@joshtriplett
Copy link
Member

@rfcbot merge

@rust-rfcbot
Copy link
Collaborator

rust-rfcbot commented Oct 22, 2025

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rust-rfcbot rust-rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Oct 22, 2025
@tmandry
Copy link
Member

tmandry commented Oct 22, 2025

@rfcbot reviewed

@joshtriplett
Copy link
Member

I agree that the lint on positional arguments isn't a blocker, though I think it's highly desirable.

@joshtriplett
Copy link
Member

operand before template

I don't think this is a problem, since it's not likely that people will expect it to work.

@traviscross
Copy link
Contributor

@folkertdev, does this just allow it for cfg or does it allow it for all attributes? E.g., would an attribute macro that expanded to cfg work here? If not, are there any other places currently in the language with a similar restriction?

@folkertdev
Copy link
Contributor Author

Macros are not currently expanded, e.g.

#![feature(asm_cfg)]

macro_rules! annotated_line {
    () => {
        #[cfg(true)]
        "ret"
    };
}

#[unsafe(no_mangle)]
pub fn square() {
    unsafe {
        std::arch::asm!(
            #[cfg(true)]
            "",
            annotated_line!(),
            #[macros::expand_to_cfg(true)]
            "",

        )
    }
}

fn main() {}

emits

error: this attribute is not supported on assembly
  --> src/main.rs:17:13
   |
17 |             #[macros::expand_to_cfg(true)]
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0658]: attributes on expressions are experimental
  --> src/main.rs:5:9
   |
 5 |         #[cfg(true)]
   |         ^^^^^^^^^^^^
...
16 |             annotated_line!(),
   |             ----------------- in this macro invocation
   |

I don't think we currently allow attributes on arguments to builtin macros. E.g. cfg is not allowed on the template parameter of println! etc.

I'll look at what we can do here, but I suspect it'll be tricky.

@traviscross
Copy link
Contributor

traviscross commented Oct 23, 2025

I don't think we currently allow attributes on arguments to builtin macros. E.g. cfg is not allowed on the template parameter of println! etc.

It seems we do allow attributes here.

println!(#[allow(unused)] ""); //~ OK
println!(#[cfg(true)] ""); //~ OK

We don't allow removing expressions here though.

println!(#[cfg(false)] ""); //~ ERROR

(Edit: When I had tested this, I was in a file where I had enabled stmt_expr_attributes for an unrelated reason and didn't notice.)

reference PR: forthcoming (though maybe none is needed?)

The relevant parts of the Reference are attributes.allowed-positions, cfg.attr.allowed-positions, and cfg.cfg_attr.allowed-positions.

The latter two say:

The cfg attribute may be used anywhere attributes are allowed.

The cfg_attr attribute may be used anywhere attributes are allowed.

What would be a bit less than elegant would be to have to say, "the cfg/cfg_attr attributes may be used anywhere attributes are allowed and on arguments to the following macros...". It'd be more elegant if we could add arguments to these macros to the list of places that attributes are allowed and then keep the allowed-positions rules on cfg/cfg_attr untouched.

@petrochenkov
Copy link
Contributor

@folkertdev, does this just allow it for cfg or does it allow it for all attributes? E.g., would an attribute macro that expanded to cfg work here? If not, are there any other places currently in the language with a similar restriction?

cfg in asm are a part of asm's DSL mimicking attributes, and are entirely unrelated to cfg attributes from the language proper.
Not sure whether it's a good style or not.
Technically they could use some other syntax, and still work in the same way as now.

So anything that these "attributes" can potentially do (eager expansion or something else) needs to be implemented manually by the asm macro and is not guaranteed to match behavior of real attributes in language-supported expansion points.

@folkertdev
Copy link
Contributor Author

It seems we do allow attributes here.

println!(#[allow(unused)] ""); //~ OK
println!(#[cfg(true)] ""); //~ OK

This is really an implementation detail. Actually println!(#[cfg(true)] "") does emit

error[E0658]: attributes on expressions are experimental
 --> src/main.rs:3:9
  |
3 |         #[cfg(true)]
  |         ^^^^^^^^^^^^
  |
  = note: see issue #15701 <https://github.com/rust-lang/rust/issues/15701> for more information

The allow attribute is just already allowed on expressions (so that error message is not complete).


We do actually parse arbitrary attributes on the assembly arguments, but anything besides cfg and cfg_attr is rejected with:

error: this attribute is not supported on assembly
 --> src/main.rs:3:9
  |
3 |         #[bar]
  |         ^^^^^^

@traviscross
Copy link
Contributor

This is really an implementation detail. Actually println!(#[cfg(true)] "") does emit

Oops... when I tested this, I was in a file where I'd enabled stmt_expr_attributes for an unrelated reason (testing closure capture behavior with rustc_capture_analysis) and didn't notice.

@traviscross traviscross changed the title stabilize asm_cfg Stabilize asm_cfg Oct 23, 2025
@folkertdev
Copy link
Contributor Author

So just to summarize: using procedural macros on assembly is rejected when the asm! macro is expanded. Arbitrary attributes parse on lines of assembly, but only cfg and cfg_attr are allowed by the expansion. We can expand the set of accepted attributes over time (e.g. rustfmt::skip or allow(...) also seem OK.

Accepting procedural macros that expand to cfg (so, eager expansion), seems difficult and not that necessary. We're not blocking adding it in the future though.

A macro-by-example macro that expands to a string literal with a cfg currently is also rejected. When attributes on expressions are stabilized, that will need some attention (not just for asm!, but also for the format_args! family of macros, possibly for others.

So I don't see blockers here for this particular feature.

@traviscross
Copy link
Contributor

traviscross commented Oct 24, 2025

Thanks. Agreed. For my part, I want to see the Reference PR, then I'll check a box.

On the Reference PR, we need to update the grammar in:

We need to add this to the allowed position list in:

(The item for this should link to the rule described below.)

Let's please write out the rules you just mentioned, about what's accepted and what is not, in:

It'll be a new rule, e.g. asm.ts-args.attributes.

(Edit: Actually, it'll need to go elsewhere... we'll work that out in the Reference PR.)

If you have any general questions about this, please reach out in Zulip in t-lang-docs/reference.

@traviscross traviscross added the S-waiting-on-documentation Status: Waiting on approved PRs to documentation before merging label Oct 24, 2025
@folkertdev
Copy link
Contributor Author

The reference PR is up at rust-lang/reference#2063

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-compiler-builtins Area: compiler-builtins (https://github.com/rust-lang/compiler-builtins) disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. S-waiting-on-documentation Status: Waiting on approved PRs to documentation before merging S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tracking Issue for asm_cfg: #[cfg(...)] within asm!

7 participants